#include "paintingengine.h"
#include <common/constants.h>

#include <QPainter>
#include <QPen>
#include <QDebug>
#include <QFile>
#include <QTextStream>

enum Warn{WarnDebugMessage=true};
using namespace Constants;

PaintingPixmap::PaintingPixmap():m_modelofpatientdatas(0)
{
    m_set = new settings;
    m_bmiManager = new BmiManager(this);
    m_zoom = 1;
    m_slidermonth = 0;
    m_lineswidhth = m_set->value(LINES_WIDTH).toInt();
    m_adjust_vertical_line = m_set->value(ADJUST_VERTICAL_LINE).toInt();
    /*QStringList listOfPointsInDays;
    listOfPointsInDays = m_bmiManager->getListOfPointsInDays();*/
}

PaintingPixmap::~PaintingPixmap(){}

void PaintingPixmap::setDatas(QStandardItemModel * modelofpatientdatas,QString & sexe, int month)
{
    m_sex  = sexe;
    m_modelofpatientdatas = modelofpatientdatas;
    m_slidermonth = month;
}

void PaintingPixmap::setRect(float x, float y)
{
    QPixmap pix(x+3161,y);
    m_pixmap = pix;
    m_paintingLabelWidht = x+3161;
    m_paintingLabelHeight = y; 
}

QPixmap PaintingPixmap::getPixmap()
{
    return m_pixmap;
}

void PaintingPixmap::setPixmapZoom(float zoom)
{
    m_zoom = zoom;
    if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__) << " ZOOM =" << QString::number(m_zoom)  ;
}

float PaintingPixmap::getBmi(double y,int zoom)
{
    QStandardItemModel * modelBmi = new QStandardItemModel;
    if (m_sex.contains("F"))
    {
    	  modelBmi = m_bmiManager->getBmiFemale();
    	  if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__) << " FEMALE " ;
    	 }
    if(m_sex.contains("M"))
    {
          modelBmi = m_bmiManager->getBmiMale();
          if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__) << " MALE " ;
        }
    float heightMultiplicator = m_set->value(Constants::Y_MULTIPLIER).toFloat();
    float bmiReduced = modelBmi->data(modelBmi->index(0,SD_AVERAGE_SD),Qt::DisplayRole).toFloat()*heightMultiplicator;
    float bmi = modelBmi->data(modelBmi->index(1,SD_AVERAGE_SD),Qt::DisplayRole).toFloat()*heightMultiplicator;
    float bmiNext = modelBmi->data(modelBmi->index(2,SD_AVERAGE_SD),Qt::DisplayRole).toFloat()*heightMultiplicator;
    /*float y = m_paintingLabelHeight - ((bmi - bmiReduced ) * m_zoom);
    float yNext = m_paintingLabelHeight - ((bmiNext - bmiReduced ) * m_zoom);*/
    float result = (bmiReduced + (( m_paintingLabelHeight -y)/zoom))/heightMultiplicator;
    if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__) << " result =" << QString::number(result) ;
    
    return result;
}

void PaintingPixmap::paint()
{
    qWarning() << __FILE__ << QString::number(__LINE__) << " PAINT "  ;
    int patientPointWidth = m_set->value(PATIENT_POINT_WIDTH).toInt();
    int two_sd_width = m_set->value(TWO_SD_WIDTH).toInt();
    int one_and_half_sd_width = m_set->value(ONE_AND_HALF_SD_WIDTH).toInt();
    int one_sd_width = m_set->value(ONE_SD_WIDTH).toInt();
    int half_sd_width = m_set->value(HALF_SD_WIDTH).toInt();
    int average_sd = m_set->value(AVERAGE_SD).toInt();
    QStandardItemModel * modelBmi = new QStandardItemModel;
    if (m_sex.contains("F"))
    {
    	  modelBmi = m_bmiManager->getBmiFemale();
    	  qWarning() << __FILE__ << QString::number(__LINE__) << " FEMALE " ;
        }
    if(m_sex.contains("M"))
    {
          modelBmi = m_bmiManager->getBmiMale();
          qWarning() << __FILE__ << QString::number(__LINE__) << " MALE " ;
        }
    qDebug() << __FILE__ << QString::number(__LINE__) << " modelBmi count  =" << QString::number(modelBmi->rowCount()) ;
   /*QFile file("alllifebmi.csv")  ;
    if (!file.open(QIODevice::ReadOnly))
    {
    	  qWarning() << __FILE__ << QString::number(__LINE__) << "unable to open file allLifeMaleAndFemaleBmi.csv" ;
        }
    QTextStream stream(&file);
    while (!stream.atEnd())
    {
        QString line = stream.readLine();
        if (line.isEmpty())
        {
              break;
            }
        QStringList listinline = line.split(";");
        QString sexint = "1";
        if (m_sex=="F")
        {
              sexint = "2";
            }
        if (!listinline[0].contains(sexint))
        {
              break;
            }
        QList<QStandardItem*> listofdatas;
        for ( int col = 0; col < listinline.size(); ++ col)
        {
              QString data = listinline[col];
              if (data.isEmpty())
              {
                    break;
                  }
              QStandardItem * item = new QStandardItem(data);
              listofdatas << item;
            }
            modelBmi->appendRow(listofdatas);
        }*/
    qDebug() << __FILE__ << QString::number(__LINE__) << " ROWS MODELBMI =" << QString::number(modelBmi->rowCount()) ;
    QHash<int,QPen> hashOfPens;
    //-2SD +2SD
    QColor   red(Qt::red);
    QBrush   rouge(red);
    QPen     penTwoSD(rouge, two_sd_width , Qt::SolidLine , Qt::SquareCap , Qt::RoundJoin); 
    hashOfPens.insert(SD_LESS_TWO_SD,penTwoSD);
    hashOfPens.insert(SD_PLUS_TWO_SD,penTwoSD);
    //-1.5 +1.5   
    QColor   blue(Qt::blue);
    QBrush   bleu(blue);
    QPen     penOneAndHalfSD(bleu, one_and_half_sd_width , Qt::SolidLine  , Qt::SquareCap , Qt::RoundJoin);
    hashOfPens.insert(SD_LESS_ONE_AND_HALF_SD,penOneAndHalfSD);
    hashOfPens.insert(SD_PLUS_ONE_AND_HALF_SD,penOneAndHalfSD);
    //+1 -1
    QColor   magenta(Qt::magenta);
    QBrush   magentaBrush(magenta);
    QPen     penOneSD(magentaBrush, one_sd_width , Qt::SolidLine  , Qt::SquareCap , Qt::RoundJoin);
    hashOfPens.insert(SD_LESS_ONE_SD,penOneSD);
    hashOfPens.insert(SD_PLUS_ONE_SD,penOneSD);
    //-O.5 +0.5
    QColor   green(Qt::green);
    QBrush   vert(green);
    QPen     penHalfSD(vert, half_sd_width , Qt::SolidLine  , Qt::SquareCap , Qt::RoundJoin);
    hashOfPens.insert(SD_LESS_HALF_SD,penHalfSD);
    hashOfPens.insert(SD_PLUS_HALF_SD,penHalfSD);
    //average
    QColor   grey(Qt::gray);
    QBrush   gris(grey);
    QPen     penAverageSD(gris, average_sd , Qt::SolidLine  , Qt::SquareCap , Qt::RoundJoin);
    hashOfPens.insert(SD_AVERAGE_SD,penAverageSD);
    //w and h patient
    QColor   black(Qt::black);    
    QBrush   noir(black);
    QPen     patientPen(noir, patientPointWidth , Qt::SolidLine  , Qt::SquareCap , Qt::RoundJoin);
    //lines width
    QPen     linesPen(noir, m_lineswidhth , Qt::SolidLine  , Qt::SquareCap , Qt::RoundJoin);    
    
    QPainter paint(&m_pixmap);
    paint.fillRect(0,0,m_paintingLabelWidht,m_paintingLabelHeight,Qt::white);
    paint.setRenderHint(QPainter::Antialiasing);    
    //half month = 15.2
    if (WarnDebugMessage)
        qDebug() << __FILE__ << QString::number(__LINE__) << " m_zoom =" << QString::number(m_zoom) ;
    //parameters
    float heightMultiplicator = m_set->value(Constants::Y_MULTIPLIER).toFloat();
    //heightMultiplicator = 1.00;
    float widthMultiplicator = m_set->value(Constants::X_MULTIPLIER).toFloat();
    qWarning() << __FILE__ << QString::number(__LINE__) << " X_MULTIPLIER = " << QString::number(widthMultiplicator)
                                                        << " Y_MULTIPLIER = " << QString::number(heightMultiplicator) ;
    
    float yReduced = modelBmi->data(modelBmi->index(0,SD_AVERAGE_SD),Qt::DisplayRole).toFloat()* heightMultiplicator;
    //yReduced = modelBmi->data(modelBmi->index(0,SD_AVERAGE_SD),Qt::DisplayRole).toFloat();
    if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__) << " yReduced =" << QString::number(yReduced) ;
    if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__) << " m_paintingLabelHeight =" << QString::number(m_paintingLabelHeight) ;
    if (WarnDebugMessage) qDebug() << __FILE__ << QString::number(__LINE__) << " m_paintingLabelWidht =" << QString::number(m_paintingLabelWidht) ;

    for (int sd = SD_LESS_TWO_SD; sd < SD_MaxParam; ++sd)
    {
        paint.setPen(hashOfPens.value(sd));
        //qDebug() << __FILE__ << QString::number(__LINE__) << " WIDTH =" << QString::number(hashOfPens.value(sd).widthF()) ;
        for (int row = 0; row < modelBmi->rowCount()-1; ++row)
        {
   	        float x = modelBmi->data(modelBmi->index(row,SD_MONTH),Qt::DisplayRole).toFloat() * widthMultiplicator;
   	        float xNext = modelBmi->data(modelBmi->index(row+1,SD_MONTH),Qt::DisplayRole).toFloat() * widthMultiplicator;
   	        float y = modelBmi->data(modelBmi->index(row,sd),Qt::DisplayRole).toFloat()* heightMultiplicator;
   	        float yNext = modelBmi->data(modelBmi->index(row+1,sd),Qt::DisplayRole).toFloat() * heightMultiplicator;
   	          paint.drawLine(QLineF(
   	                         x  * m_zoom,
   	                         m_paintingLabelHeight - ((y - yReduced ) * m_zoom) ,
   	                         xNext * m_zoom,
   	                         m_paintingLabelHeight - ((yNext - yReduced ) * m_zoom ) 
   	                         ));
  	                        
            }//for
        }//for
    //paint patient points
    paint.setPen(patientPen);
    for ( int r = 0; r < m_modelofpatientdatas->rowCount(); ++ r)
    {
          QDate date = m_modelofpatientdatas->data(m_modelofpatientdatas->index(r,DATE),Qt::DisplayRole).toDate();
          QDate birthday = m_modelofpatientdatas->data(m_modelofpatientdatas->index(r,DATE_OF_BIRTH_DATA),Qt::DisplayRole).toDate();
          float dateInMonths = m_bmiManager->calcDateInMonthsSinceBirthday(date,birthday);
          float bmi = m_bmiManager->calcBmiFromWeightAndHeight
                                       (m_modelofpatientdatas->data(m_modelofpatientdatas->index(r,WEIGHT),Qt::DisplayRole).toFloat(),
                                        m_modelofpatientdatas->data(m_modelofpatientdatas->index(r,HEIGHT),Qt::DisplayRole).toFloat());
          float x = dateInMonths * widthMultiplicator;
          float y = bmi * heightMultiplicator;          
          paint.drawPoint(x*m_zoom,m_paintingLabelHeight - ((y - yReduced ) * m_zoom) );
        }
     //paint month line
     paint.setPen(linesPen);
     int monthSlideValue = m_slidermonth;
     float xmonth = monthSlideValue*widthMultiplicator*m_zoom + m_adjust_vertical_line*widthMultiplicator*m_zoom;
     paint.drawLine(xmonth,0,xmonth,m_paintingLabelHeight);     

     paint.end();    
}
